package com.itheima.task;

import com.google.common.collect.Sets;
import com.itheima.common.constant.MessageConstant;
import com.itheima.common.utils.AliOssUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.Optional;
import java.util.Set;

@Component
@Slf4j
@RequiredArgsConstructor
public class ImageCleanupTask {
    private final RedisTemplate redisTemplate;
    private final AliOssUtil aliOssUtil;

    @Scheduled(cron ="0 0 * * * *")
    public void cleanupImages() {
        log.info("开始清理图片");
        try {
            // 定义带前缀的键名
            String uploadKey = "JunkPhotos:" + MessageConstant.UPLOAD_KEY;
            String addKey = "JunkPhotos:" + MessageConstant.ADD_KEY;

            // 1. 从redis里获得两个集合
            Set<String> uploadedSet = redisTemplate.opsForSet().members(uploadKey);
            Set<String> usedSet = redisTemplate.opsForSet().members(addKey);

            if (uploadedSet == null || uploadedSet.isEmpty()) {
                log.info("无上传图片，跳过清理");
                return;
            }

            // 2. 计算垃圾图片得到垃圾照片的集合（上传但未使用）
            Set<String> garbageImages = Sets.difference(
                    Optional.of(uploadedSet).orElse(Collections.emptySet()),
                    Optional.ofNullable(usedSet).orElse(Collections.emptySet())
            );

            if (garbageImages.isEmpty()) {
                log.info("未发现垃圾图片");
                return;
            }

            log.info("发现 {} 个垃圾图片", garbageImages.size());
            garbageImages.forEach(img -> log.debug("垃圾图片: {}", img));

            // 3. 删除OSS文件
            garbageImages.forEach(imageUrl -> {
                // 更健壮的对象名提取方法
                String objectName = extractObjectName(imageUrl);
                try {
                    aliOssUtil.delete(objectName);
                    log.info("已删除OSS文件: {}", objectName);

                    // 4. 同步删除Redis记录（使用相同的键前缀）
                    redisTemplate.opsForSet().remove(uploadKey, imageUrl);
                } catch (Exception e) {
                    log.error("删除失败: {} - {}", objectName, e.getMessage());
                }
            });

            log.info("清理完成，共删除 {} 个文件", garbageImages.size());

        } catch (Exception e) {
            log.error("图片清理异常", e);
        }
    }

    // 值的对象名提取方法
    private String extractObjectName(String imageUrl) {
        try {
            // 去除URL参数和路径
            String baseUrl = imageUrl.split("\\?")[0];
            return baseUrl.substring(baseUrl.lastIndexOf("/") + 1);
        } catch (Exception e) {
            log.warn("无法解析对象名: {}", imageUrl);
            // 尝试直接使用最后部分
            String[] parts = imageUrl.split("/");
            return parts[parts.length - 1];
        }
    }}